package com.example.myapplication;

import java.util.ArrayList;
import java.util.*;
import java.util.UUID;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.MessageDigest;

 class helpFunc {
    static short bs = 30000;
    static int g_packId=0;
    //	static String serviceKey = "bigSalt";
//	public static short pushAhead=2000;
    //public static int packLimit=1400;
    public static int con_close=66;
    //public static int con_localPort = 9997;
    //public static int con_portDecreaseDose=1;
    //public static String con_serverIp = "154.221.19.38";//"192.168.43.173";
    //public static int con_serverPort = 19022;
    //public static String con_serverIp = "192.168.43.173";
//	public static int speedLimit = 250;
//	public static int perSecondPortsLimit=50;
    public static int minPackGot=100;
    public static double con_maxRate = 0.5;
    public static double con_minRate = 0.08;
    public static double timeoutTime = 1;
    public static int speedLimit_portNum = 10;
    //public static int	con_portIncreaseDose=3;
    public static byte[] uuid,con;
    public static int recLen = 10240;
    public static int regulateTimeSpan=1;
    public static int con_streamBufferSize = 200 * 1024;
    //public static int maxPortNum = 100;
    public static int 	minPortNum = 10;
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static short circleBig(short a, short b) {
        if (a == b)
            return a;
        if ((a > b) && ((a - b) < (bs / 2)))
            return a;
        if ((a < b) && ((b - a) > (bs / 2)))
            return a;
        return b;
    }

    public static short circleAddOne(short a) {
        if (a == bs - 1)
            return 0;
        return (short) (a + 1);
    }

    public static short circleAdd(short a, short b) {
        short ret = a;
        for (short i = 0; i < b; i++) {
            ret = circleAddOne(ret);
        }

        return ret;
    }

    public static ArrayList<Short> circleRange(short a, short b) {
        short temp = a;
        ArrayList<Short> ret = new ArrayList<Short>();
        while (true) {
            if (temp == circleBig(b, temp))
                break;
            ret.add(temp);
            temp = circleAdd(temp, (short) 1);
        }
        return ret;

    }

    public static double getTime() {
        return System.currentTimeMillis() / (double) 1000;
    }

    public static void addPackSta(Map<String, packStaData> m, short v, double ti) {
        if (ti == 0 || ti == -Double.MAX_VALUE) {
            ti = getTime();
        }
        String u = UUID.randomUUID().toString();
        m.put(u, new packStaData(ti, v));
    }

    public static String getMulString(String a, int n) {
        String	ret =new String();
        for (int i = 0; i < n; i++) {
            ret+=  a;
        }
        return ret;
    }

    public static short getPackStaBigV(Map<String, packStaData> m) {
        short mv = 0;
        for (String k : m.keySet()) {
            packStaData v = m.get(k);
            if (getTime() - v.time < 1 && v.v > mv)
                mv = v.v;
        }
        return mv;
    }
    public static void  clearPackSta(Map<String, packStaData> m)
    {
        ArrayList<String> k = new ArrayList<String>(m.keySet());
        for(String i:k)
        {
            if(m.get(i).time<getTime()-1)
                m.remove(i);
        }
    }
    public static void print(String a) {
        System.out.println(a);
    }

    public static void  makePack  (byte[] s,byte[] salt) throws Exception
    {
        g_packId+=1;
        if (g_packId>30000)g_packId=0;
        structWrapper w= new structWrapper(s.length+6);
        w.writeWord((short)g_packId);
        w.writeArr(s);
        MessageDigest md=	 MessageDigest.getInstance("MD5");
        md.update(w.data,0,s.length+2);
        md.update(salt);
        byte[] aa=md.digest();
        System.arraycopy(aa, 0, w.data, s.length+2, 4);
        uuid = new byte[2];

        System.arraycopy(w.data,0,uuid,0,2);
        con = w.data;
    }
    public static byte[]  getuuid_byte() throws Exception
    {
        return MessageDigest.getInstance("MD5").digest( UUID.randomUUID().toString().getBytes());
    }
    public static byte[] bufAdd( byte[] a, byte[] b)
    {
        byte[] newMd5 = new byte[a.length+b.length];
        System.arraycopy(a, 0, newMd5, 0, a.length);
        System.arraycopy(b, 0, newMd5, a.length, b.length);
        return newMd5;
    }

    public static void checkPackValid2(byte[] s,byte[] salt)
            throws Exception
    {
        if(s.length<4)
        {
            uuid = new byte[0];
            con = new byte[0];
            return;
        }

        MessageDigest md=	 MessageDigest.getInstance("MD5");
        md.update(s,0,s.length-4);
        md.update(salt);

        byte[] aa=md.digest();
        byte[] newMd5 = new byte[4];
        System.arraycopy(aa, 0, newMd5, 0, 4);
        byte[] oriMd5 = new byte[4];
        System.arraycopy(s,s.length-4,oriMd5,0,4);

        if(!Arrays.equals(newMd5,oriMd5))
        {
            uuid = new byte[0];
            con = new byte[0];
            return;
        }
        uuid = new byte[2];
        con = new byte[s.length-6];
        System.arraycopy(s,0,uuid,0,2);
        System.arraycopy(s,2,con,0,s.length-6);
    }
}

class structWrapper {
    byte[] data;
    int pos;
    int leftLen()
    {
        return data.length-pos;}
    structWrapper(int l) {
        data = new byte[l];
        pos = 0;
    }

    structWrapper(byte[] data2) {
        data = data2;
        pos = 0;
    }

    public void writeByte(byte b) {
        data[pos] = b;
        pos += 1;
    }

    public void writeWord(short s) {
        byte[] t = ByteBuffer.allocate(2).order(ByteOrder.nativeOrder()).putShort(s).array();
        System.arraycopy(t, 0, data, pos, 2);
        pos += 2;
    }

    public void writeDWord(int s) {
        byte[] t = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(s).array();
        System.arraycopy(t, 0, data, pos, 4);
        pos += 4;
    }

    public void writeArr(byte[] s)
    {
        System.arraycopy(s, 0, data, pos, s.length);
        pos +=  s.length;
    }
    public byte[] readArr(int n)
    {
        byte[] re=	new byte[n];

        System.arraycopy(data, pos, re, 0,n);
        pos +=  n;
        return re;
    }

    public void writeDouble(double d) {
        byte[] t = ByteBuffer.allocate(8).order(ByteOrder.nativeOrder()).putDouble(d).array();
        System.arraycopy(t, 0, data, pos, 8);
        pos += 8;
    }

    public byte[] getWriteData() {
        byte[] d = new byte[pos];
        System.arraycopy(data, 0, d, 0, pos);
        return d;
    }

    public byte readByte() {
        pos += 1;
        return data[pos - 1];

    }

    public short readWord() {
        pos += 2;
        return ByteBuffer.wrap(data, pos - 2, 2).order(ByteOrder.nativeOrder()).getShort();
    }
    public int readDWord() {
        pos += 4;
        return ByteBuffer.wrap(data, pos - 4, 4).order(ByteOrder.nativeOrder()).getInt();
    }
    public double readDouble() {
        pos += 8;
        return ByteBuffer.wrap(data, pos - 8, 8).order(ByteOrder.nativeOrder()).getDouble();
    }

    public byte[] getLeftData() {
        byte[] d = new byte[data.length - pos];
        System.arraycopy(data, pos, d, 0, data.length - pos);
        return d;
    }
}
